/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MaquinaVirtual;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author David
 */

enum errorEj{
ERROR_INSTRUCCION_DESCONOCIDA,ERROR_DIVISION_POR_CERO , ERROR_EJEC_TIPOS,
ERROR_PARAMETRO_NO_ESPERADO,FALTA_OPERANDO
};
public class MaquinaVirtual {

    /**
     * @param args the command line arguments
     */
    
    private int _contadorPrograma;
 //   private int _cimaPila;
    private boolean _regParada;
    private Stack _pila;
    private ArrayList _memoriaDatos;
    private ArrayList<String> _memoriaInstrucciones;
    private FileReader fr;
    private BufferedReader br;

    private boolean error;
    private errorEj errorEjec;
   // private Class class
    
    //True=1 , False=0{}
    public MaquinaVirtual()
    {
        this.error=false;
        this.errorEjec=null;
        this._memoriaDatos=new ArrayList();
        this._memoriaInstrucciones=new ArrayList<String>();
        this._pila= new Stack();
        
        
        try {
            this.fr = new FileReader("archivo.obj");
            this.br = new BufferedReader(this.fr);
        } catch (FileNotFoundException ex) 
        {
            Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
        }
        String inst;
        try {
            inst = br.readLine();
            while ( inst!= null)
            {
                _memoriaInstrucciones.add(inst);
                inst = br.readLine();
            }
        } catch (IOException ex) {
            Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
        }

        
    }
    public MaquinaVirtual(String nomFichero)
    {

        this.error=false;
        this.errorEjec=null;
        this._memoriaDatos=new ArrayList();
        this._memoriaInstrucciones=new ArrayList<String>();
        this._pila= new Stack();
        
        
        try {
            this.fr = new FileReader(nomFichero);
            this.br = new BufferedReader(this.fr);
        } catch (FileNotFoundException ex) 
        {
            Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
        }
        String inst;
        try {
            inst = br.readLine();
            while ( inst!= null)
            {
                _memoriaInstrucciones.add(inst);
                inst = br.readLine();
            }
        } catch (IOException ex) {
            Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
        }

        
    }
    
    public void cargaMemInstrucciones(ArrayList<String> mIns)
    {
        _memoriaInstrucciones=mIns;
    }
    
    public void ejecutaMaquina()
    {
        _contadorPrograma=0;
        //_cimaPila=0;
        _regParada=true;
        String instruccion=_memoriaInstrucciones.get(_contadorPrograma);
        while(!(instruccion.equals("stop"))&& !error)
        {
            ejcutaInstruccion(instruccion);
            instruccion=_memoriaInstrucciones.get(_contadorPrograma);
        }
        if(error)
        {
            System.out.println(this.errorEjec);
        }
        
    }

    void ejecutaMaquinaTraza() {
       
        _contadorPrograma=0;
        //_cimaPila=0;
        
        ArrayList<Integer> posMem=new ArrayList<Integer>();
        String instruccion=_memoriaInstrucciones.get(_contadorPrograma);
        br = new BufferedReader(new InputStreamReader(System.in));
        while(!(instruccion.equals("stop"))&& !error)
        {
            
           if (instruccion.startsWith("desapila_dir(") && instruccion.endsWith(")"))
               posMem.add((Integer)dameParametro(instruccion));
         
            try {

                System.out.println("Instrucción Pila: " + instruccion);
                System.out.println("*****************************************");
                System.out.println("Contenido Pila: ");
                if (this._pila.empty()) {
                    System.out.println("Pila Vacia");
                } else {
                    
                    for (int i = 0; i < this._pila.size()-1; i++) {
                        System.out.println("Pila[" + i + "]: " + this._pila.get(i));
                    }
                    System.out.println("Cima Pila: " + this._pila.peek());
                }
                System.out.println("*****************************************");
                System.out.println("Contenido Memoria de Datos: ");
               
                if (this._memoriaDatos.size() < 1) {
                    System.out.println("No contiene datos");
                } else {
                    for (int i = 0; i < posMem.size(); i++) {
                        System.out.println("MemoriaDatos[" + posMem.get(i) + "]: " + this._memoriaDatos.get(posMem.get(i)));
                    }
                }
                System.out.println("*****************************************");
                System.out.println("*****************************************");
                System.out.println();
                System.out.println();

                ejcutaInstruccion(instruccion);


                if(instruccion.equals("apila_entradaReal")||instruccion.equals("apila_entradaEntero")||instruccion.equals("apila_entradaNatural")||
                        instruccion.equals("apila_entradaChar")||instruccion.equals("apila_entradaBooleano"))
                {}
                else
                    br.readLine();
                
                instruccion = _memoriaInstrucciones.get(_contadorPrograma);
            } catch (IOException ex) {
                Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        if(error )
        {
            System.out.println(this.errorEjec);
        }
        
    }

    private void absoluto() {

        try {
            if (this._pila.size() >= 1) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Boolean) || (op1 instanceof Character)) {

                    error = true;
                    errorEjec = errorEj.ERROR_EJEC_TIPOS;

                } else if ((op1 instanceof Float)) {
                    Float op = ((Float) op1).floatValue();
                    if (op < 0) {
                        this._pila.push(-op);
                        this._contadorPrograma++;
                    } else {
                        this._pila.push(op);
                        this._contadorPrograma++;
                    }
                } else if ((op1 instanceof Integer)) {
                    Integer op = ((Integer) op1).intValue();
                    if (op < 0) {
                        this._pila.push(-op);
                        this._contadorPrograma++;
                    } else {
                        this._pila.push(op);
                        this._contadorPrograma++;
                    }
                } else {
                    error = true;
                    errorEjec = errorEj.FALTA_OPERANDO;
                }

            }
        } catch (Exception e) {
                error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
        }
    
    private void apila(Object num)
    {
        this._pila.push(num);
        this._contadorPrograma++;
    }
    
    private void apilaDir(int direccion)
    {
        if(direccion>=0 && this._memoriaDatos.get(direccion)!=null ){
            _pila.push(this._memoriaDatos.get(direccion));
            this._contadorPrograma++;
        }
    }

    

    private void apila_entradaBooleano() {
        System.out.println("Introduzca entrada por consola y pulse Enter: ");
        System.out.println();
        br = new BufferedReader(new InputStreamReader(System.in));
       String sTexto=null;
      
            try {
                
                sTexto = br.readLine();
            } catch (IOException ex) {
                Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
            }
        

       if(sTexto.equals("true"))
       {
            this._pila.push(Boolean.TRUE);
            this._contadorPrograma++;
       }
       else if(sTexto.equals("false"))
       {
            this._pila.push(Boolean.FALSE);
            this._contadorPrograma++;
       }else
       {
            error=true;
            errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;

       }
       
    }

    private void apila_entradaChar() {
        System.out.println("Introduzca entrada por consola y pulse Enter: ");
        System.out.println();
        br = new BufferedReader(new InputStreamReader(System.in));
       String sTexto=null;
 
            try {
                sTexto = br.readLine();
            } catch (IOException ex) {
                Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
            }
       if(sTexto.length()==1){
                   this._pila.push(sTexto.charAt(0));
                   this._contadorPrograma++;
       }else
       {
            error=true;
            errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
       }
       
    }

    private void apila_entradaEntero() {
        System.out.println("Introduzca entrada por consola y pulse Enter: ");
        System.out.println();
        br = new BufferedReader(new InputStreamReader(System.in));
       String sTexto=null;

            try {
                sTexto = br.readLine();
            } catch (IOException ex) {
                Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
            }

       try
       {
            Integer num=Integer.parseInt(sTexto);
            if(num!=null)
            {
                this._pila.push(num);
                this._contadorPrograma++;
            }else
            {
                error=true;
                errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
            }

       }catch(Exception e)
       {
           error=true;
           errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
       }
       
    }

    private void apila_entradaNatural() {
       System.out.println("Introduzca entrada por consola y pulse Enter: ");
        System.out.println();
        br = new BufferedReader(new InputStreamReader(System.in));
       String sTexto=null;
            try {
                sTexto = br.readLine();
            } catch (IOException ex) {
                Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
            }
       try
       {
            Integer num=Integer.parseInt(sTexto);
            if(num!=null)
            {
                if(num>=0){
                this._pila.push(num);
                this._contadorPrograma++;
                }
                else
                {
                    error=true;
                    errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
                }
            }else
            {
                error=true;
                errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
            }

       }catch(Exception e)
       {
           error=true;
           errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
       }
    }

    private void apila_entradaReal() {
        System.out.println("Introduzca entrada por consola y pulse Enter: ");
        System.out.println();
        br = new BufferedReader(new InputStreamReader(System.in));
       String sTexto=null;

            try {
                sTexto = br.readLine();
            } catch (IOException ex) {
                Logger.getLogger(MaquinaVirtual.class.getName()).log(Level.SEVERE, null, ex);
            }
            try
       {
            Float num=Float.parseFloat(sTexto);
            if(num!=null)
            {
                this._pila.push(num);
                this._contadorPrograma++;
            }else
            {
                error=true;
                errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
            }

       }catch(Exception e)
       {
           error=true;
           errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
       }
    }

     private void castingChar() {


         try {
             int val;
             if (this._pila.size() >= 1) {
                 Object op1 = this._pila.peek();
                 this._pila.pop();
                 if ((op1 instanceof Character) ){

                     Character op = (Character) op1;
                     this._pila.push(op);
                     this._contadorPrograma++;}

                 else if ((op1 instanceof Integer) && (val=((Integer) op1).intValue()) >= 0){

                     
                     Character op=(char) val;

                     this._pila.push(op);
                     this._contadorPrograma++;

                 } else {
                     error = true;
                     errorEjec = errorEj.ERROR_EJEC_TIPOS;
                 }
             } else {
                 error = true;
                 errorEjec = errorEj.FALTA_OPERANDO;
             }
         } catch (Exception e) {

             error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
         }

    }

    private void castingEntero() {

        try {

            if (this._pila.size() >= 1) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Boolean)) {

                    error = true;
                    errorEjec = errorEj.ERROR_EJEC_TIPOS;

                } else if ((op1 instanceof Float)){
                    Integer op=(int)((Float)op1).floatValue() ;
                     
                    this._pila.push(op);
                    this._contadorPrograma++;
                }if ((op1 instanceof Character)){
                    Integer op=(int)((Character)op1).charValue();
                   
                    this._pila.push(op);
                    this._contadorPrograma++;
                 }else if ((op1 instanceof Integer)){


                    this._pila.push(op1);
                    this._contadorPrograma++;}
            } else {
                error = true;
                errorEjec = errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
            //error
    }

    private void castingNatural() {

        try {
            if (this._pila.size() >= 1) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op1 instanceof Integer && ((Integer) op1).intValue() <0)) {

                    error = true;
                    errorEjec = errorEj.ERROR_PARAMETRO_NO_ESPERADO;

                } else {
                    if (op1 instanceof Character) {

                        Integer op = (Integer) op1;
                        this._pila.push(op);
                        this._contadorPrograma++;
                    } else if (op1 instanceof Integer && ((Integer) op1).intValue() >= 0) {
                        Integer op = ((Integer) op1).intValue();
                        this._pila.push(op);
                        this._contadorPrograma++;
                    }
                }
            } else {
                error = true;
                errorEjec = errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
            //error
    }

    private void castingReal()
    {
        try {
            if (this._pila.size() >= 1) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float)) {

                    this._pila.push(op1);
                    this._contadorPrograma++;

                } else if ((op1 instanceof Integer) || (op1 instanceof Integer && ((Integer) op1).intValue() >0)) {
                    String cad=op1.toString();
                    Float op=Float.parseFloat(cad);
                    this._pila.push(op);
                    this._contadorPrograma++;
                }else if (op1 instanceof Character)
                {
                    String cad=op1.toString();
                    Float op=Float.parseFloat(cad);
                    this._pila.push(op);
                    this._contadorPrograma++;
                }else
                {
                    error=true;
                errorEjec= errorEj.ERROR_PARAMETRO_NO_ESPERADO;
                }
            }
        } catch (Exception e) {
            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
}



    private Object dameParametro(String inst)
    {
        int parAbierto=inst.indexOf('(');
        int parCerrado= inst.indexOf(')');
        String param= inst.substring(parAbierto+1, parCerrado);
        if(param.equals("true"))
            return Boolean.TRUE;
        else if (param.equals("false"))
            return Boolean.FALSE;

        else if ((param.length()==3)&&(param.startsWith("'") && param.endsWith("'")))
        {
             char c=param.charAt(1);
             return c;
        }
        else
        {
           if(param.contains(".") ||param.contains("e")||param.contains("E"))
           {
                return Float.parseFloat(param);
           }
           else
               return Integer.parseInt(param);
        }

    }

    private void desapilaDir(int direccion)
    {
       if(direccion>=0 && !this._pila.empty())
           if(this._memoriaDatos.size()<= direccion)
           {
               for(int i=this._memoriaDatos.size();i<=direccion;i++)
                   this._memoriaDatos.add(null);
               this._memoriaDatos.set(direccion,this._pila.pop());
           }
           else
               this._memoriaDatos.set(direccion,this._pila.pop());
           this._contadorPrograma++;
    }

   

    private void ejcutaInstruccion(String inst)
    {
      
        
      if (inst.startsWith("apila(") && inst.endsWith(")")){ 
          apila(dameParametro(inst));
      } 
      else if (inst.startsWith("apila_dir(") && inst.endsWith(")"))
      {  
          apilaDir((Integer)dameParametro(inst));
      }                     
      else if (inst.startsWith("desapila_dir(") && inst.endsWith(")"))
      {                         
          desapilaDir((Integer)dameParametro(inst)); 
      }   
      else if (inst.equals("apila_entradaReal"))
            apila_entradaReal();
      else if (inst.equals("apila_entradaNatural"))
            apila_entradaNatural();
      else if (inst.equals("apila_entradaEntero"))
            apila_entradaEntero();
      else if (inst.equals("apila_entradaChar"))
            apila_entradaChar();
      else if (inst.equals("apila_entradaBooleano"))
            apila_entradaBooleano();
      else if (inst.equals("out"))
          salida();
      else if (inst.startsWith("out_dir(") && inst.endsWith(")"))
          salida();
      else if (inst.equals("suma"))
            suma();
      else if (inst.equals("resta"))
            resta();
      else if (inst.equals("multiplica"))
            multiplica();
      else if (inst.equals("divide"))
            divide();
      else if (inst.equals("mod"))
            modulo();
      else if (inst.equals("cambia_signo"))
            cambio_signo();
      else if (inst.equals("or"))
            or();
      else if (inst.equals("and"))
            and();
      else if (inst.equals("igual"))
            igual();
      else if (inst.equals("distinto"))
            distinto();
      else if (inst.equals("menor"))
            menor();
      else if (inst.equals("valor_absoluto"))
            absoluto();
      else if (inst.equals("menorigual"))
            menorOigual();
      else if (inst.equals("mayor"))
            mayor();
      else if (inst.equals("mayorigual"))
            mayorOigual();
      else if (inst.equals("desplaza_izquierda"))
            desplazaIzq();
      else if (inst.equals("desplaza_derecha"))
            desplazaDer();
      else if (inst.equals("niega"))
            not();
      else if (inst.equals("convierte_a_real"))
            castingReal(); 
      else if (inst.equals("convierte_a_int"))
            castingEntero();
      else if (inst.equals("convierte_a_natural"))
            castingNatural();
      else if (inst.equals("convierte_a_char"))
            castingChar();
      else
      {
                 error=true;
                errorEjec= errorEj.ERROR_INSTRUCCION_DESCONOCIDA;
      }
        
}

    

   
    private void salida() {
        if(!this._pila.empty())
        {
            System.out.println(this._pila.pop()+"\n");
            this._contadorPrograma++;

        }
        else
        {
            error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
        }


    }

    

   

    
    
    private void suma()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                    String cad=op1.toString();
                    Float op11=Float.parseFloat(cad);
                    String cad1=op0.toString();
                    Float op00=Float.parseFloat(cad1);
                    op1 = (Float) op00 + (Float) op11;
                    this._pila.push(op1);
                } else {
                    op1 = (Integer) op0 + (Integer) op1;
                    this._pila.push(op1);
                }
                this._contadorPrograma++;

            }
            else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }
    
    private void resta()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {

                    String cad=op1.toString();
                    Float op11=Float.parseFloat(cad);
                    String cad1=op0.toString();
                    Float op00=Float.parseFloat(cad1);
                    op1 = (Float) op00 - (Float) op11;
                    this._pila.push(op1);
                } else {
                    op1 = (Integer) op0 - (Integer) op1;
                    this._pila.push(op1);
                }
                this._contadorPrograma++;
            }
            else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }
    
    private void multiplica()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                    String cad=op1.toString();
                    Float op11=Float.parseFloat(cad);
                    String cad1=op0.toString();
                    Float op00=Float.parseFloat(cad1);
                    op1 = (Float) op00 * (Float) op11;
                    this._pila.push(op1);
                } else {
                    op1 = (Integer) op0 * (Integer) op1;
                    this._pila.push(op1);
                }
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {
            error=true;
            errorEjec= errorEj.ERROR_EJEC_TIPOS;

        }
    }
   
    private void divide()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                     String cad=op1.toString();
                    Float op11=Float.parseFloat(cad);
                    String cad1=op0.toString();
                    Float op00=Float.parseFloat(cad1);
                    op1 = (Float) op00 / (Float) op11;
                    this._pila.push(op1);
                } else {
                    op1 = (Integer) op0 / (Integer) op1;
                    this._pila.push(op1);
                }
                this._contadorPrograma++;
            } else {


                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;


            }
        } catch (Exception e) {

            error = true;
            errorEjec = errorEj.ERROR_DIVISION_POR_CERO;
        }
        } 
    
    
    private void modulo()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Integer) && (op0 instanceof Integer)) {
                    op1 = (Integer) op0 % (Integer) op1; /// Division por cero mostrar error;
                    this._pila.push(op1);
                    this._contadorPrograma++;
                } else {
                    error=true;
                    errorEjec= errorEj.ERROR_EJEC_TIPOS;
                }





            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error = true;
            errorEjec = errorEj.ERROR_DIVISION_POR_CERO;
        }
 
    }
    
    private void and()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Boolean) && (op0 instanceof Boolean)) {
                    op1 = (Boolean) op0 && (Boolean) op1;
                    this._pila.push(op1);
                    this._contadorPrograma++;

                } else {
                    error = true;
                    errorEjec = errorEj.ERROR_EJEC_TIPOS;
                }

            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
 
    }
    
    private void or()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Boolean) && (op0 instanceof Boolean)) {
                    op1 = (Boolean) op0 || (Boolean) op1;
                    this._pila.push(op1);
                    this._contadorPrograma++;

                } else {
                    error = true;
                    errorEjec = errorEj.ERROR_EJEC_TIPOS;
                }
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void not()
    {
        try {
            if (this._pila.size() >= 1) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Boolean)) {
                    op1 = !(Boolean) op1;
                    this._pila.push(op1);
                    this._contadorPrograma++;

                } else {
                    error = true;
                    errorEjec = errorEj.ERROR_EJEC_TIPOS;
                }


            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void cambio_signo()
    {
        try {
            if (this._pila.size() >= 1) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float)) {
                    op1 = -(Float) op1;
                    this._pila.push(op1);
                } else {
                    op1 = -(Integer) op1;
                    this._pila.push(op1);
                }
                this._contadorPrograma++;

            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {
            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void menor()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                    boolean b = (Float) op0 < (Float) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Integer) || (op0 instanceof Integer)) {
                    boolean b = (Integer) op0 < (Integer) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Character) || (op0 instanceof Character)) {
                    boolean b = (Character) op0 < (Character) op1;
                    this._pila.push(b);
                } else if ((Boolean) op0 == false && (Boolean) op1 == true) {
                    boolean b = true;
                    this._pila.push(b);
                } else {
                    boolean b = false;
                    this._pila.push(b);
                }
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void mayor()
    {
        try {
            if (this._pila.size() >= 2) {
            Object op1 = this._pila.peek();
            this._pila.pop();
            Object op0 = this._pila.peek();
            this._pila.pop();
            if ((op1 instanceof Float) || (op0 instanceof Float)) {
                boolean b = (Float) op0 > (Float) op1;
                this._pila.push(b);
            } else if ((op1 instanceof Integer) || (op0 instanceof Integer)) {
                boolean b = (Integer) op0 > (Integer) op1;
                this._pila.push(b);
            } else if ((op1 instanceof Character) || (op0 instanceof Character)) {
                boolean b = (Character) op0 > (Character) op1;
                this._pila.push(b);
            } else if ((Boolean) op0 == true && (Boolean) op1 == false) {
                boolean b = true;
                this._pila.push(b);
            } else {
                boolean b = false;
                this._pila.push(b);
            }
            this._contadorPrograma++;}else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {
            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void mayorOigual()
    {
        try {

            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                    boolean b = (Float) op0 >= (Float) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Integer) || (op0 instanceof Integer)) {
                    boolean b = (Integer) op0 >= (Integer) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Character) || (op0 instanceof Character)) {
                    boolean b = (Character) op0 >= (Character) op1;
                    this._pila.push(b);
                } else if (((Boolean) op0 == true && (Boolean) op1 == false) || ((Boolean) op0 == (Boolean) op1 == false)) {
                    boolean b = true;
                    this._pila.push(b);
                } else {
                    boolean b = false;
                    this._pila.push(b);
                }
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {
            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }//

    private void menorOigual()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                    boolean b = (Float) op0 <= (Float) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Integer) || (op0 instanceof Integer)) {
                    boolean b = (Integer) op0 <= (Integer) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Character) || (op0 instanceof Character)) {
                    boolean b = (Character) op0 <= (Character) op1;
                    this._pila.push(b);
                } else if (((Boolean) op0 == false && (Boolean) op1 == true) || ((Boolean) op0 == (Boolean) op1 == false)) {
                    boolean b = true;
                    this._pila.push(b);
                } else {
                    boolean b = false;
                    this._pila.push(b);
                }
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void igual()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                    boolean b = (Float) op0 == (Float) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Integer) || (op0 instanceof Integer)) {
                    boolean b = (Integer) op0 == (Integer) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Character) || (op0 instanceof Character)) {
                    boolean b = (Character) op0 == (Character) op1;
                    this._pila.push(b);
                } else if ((Boolean) op0 == (Boolean) op1 == false) {
                    boolean b = true;
                    this._pila.push(b);
                } else {
                    boolean b = false;
                    this._pila.push(b);
                }
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }
    private void distinto()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                if ((op1 instanceof Float) || (op0 instanceof Float)) {
                    boolean b = (Float) op0 != (Float) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Integer) || (op0 instanceof Integer)) {
                    boolean b = (Integer) op0 != (Integer) op1;
                    this._pila.push(b);
                } else if ((op1 instanceof Character) || (op0 instanceof Character)) {
                    boolean b = (Character) op0 != (Character) op1;
                    this._pila.push(b);
                } else if ((Boolean) op0 != (Boolean) op1 == false) {
                    boolean b = true;
                    this._pila.push(b);
                } else {
                    boolean b = false;
                    this._pila.push(b);
                }
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void desplazaIzq()
    {


        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                int op00 = (Integer) op0;
                int op11 = (Integer) op1;
                for (int i = 0; i < op11; i++) {
                    op00 = op00 * 2;

                }
                this._pila.push(op00);
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }

    private void desplazaDer()
    {
        try {
            if (this._pila.size() >= 2) {
                Object op1 = this._pila.peek();
                this._pila.pop();
                Object op0 = this._pila.peek();
                this._pila.pop();
                int op00 = (Integer) op0;
                int op11 = (Integer) op1;
                for (int i = 0; i < op11; i++) {
                    op00 = op00 / 2;

                }
                this._pila.push(op00);
                this._contadorPrograma++;
            }else{
                error=true;
                errorEjec= errorEj.FALTA_OPERANDO;
            }
        } catch (Exception e) {

            error=true;
                errorEjec= errorEj.ERROR_EJEC_TIPOS;
        }
    }
    
   
    

}
